var Element = require('./Element');
var TextNode = require('./TextNode');
var ElementIterator = function () {
};
ElementIterator.create = function (e, t, i) {
    var o = new ElementIterator();
    if (!(e instanceof Element || e instanceof TextNode))
        throw new Error('ElementIterator can only be used for exparser.Element or exparser.TextNode');
    o._elem = e;
    o._elemTypeLimit = i || Element;
    var s = t.split('-');
    if ('shadow' === s[0])
        o._composed = false;
    else {
        if ('composed' !== s[0])
            throw new Error('Unrecognized iterator type: ' + t);
        o._composed = true;
    }
    if ('ancestors' === s[1]) {
        o._relation = 'ancestors';
        o._order = 0;
    } else {
        if ('descendants' !== s[1])
            throw new Error('Unrecognized iterator type: ' + t);
        o._relation = 'descendants';
        if ('root' !== s[2])
            throw new Error('Unrecognized iterator type: ' + t);
        if ('first' === s[3])
            o._order = -1;
        else {
            if ('last' !== s[3])
                throw new Error('Unrecognized iterator type: ' + t);
            o._order = 1;
        }
    }
    return o;
};
var o = function (e, t, i, n, a) {
    if (n < 0 && e instanceof t && false === a(e))
        return false;
    var r = i && e.__wxSlotChildren || e.childNodes;
    if (r)
        for (var s = 0; s < r.length; s++)
            if (false === o(r[s], t, i, n, a))
                return false;
    return !(n > 0 && e instanceof t && false === a(e));
};
ElementIterator.prototype.forEach = function (e) {
    return 'ancestors' === this._relation ? function (e, t, i, n) {
        for (; e; e = i && (e.__wxSlotParent || e.__wxHost) || e.parentNode)
            if (e instanceof t && false === n(e))
                return false;
        return true;
    }(this._elem, this._elemTypeLimit, this._composed, e) : o(this._elem, this._elemTypeLimit, this._composed, this._order, e);
};
module.exports = ElementIterator;
